/***************************************************************************************************************************************
 * Copyright (C) 2001-2012 LearnLift USA																	*
 * Contact: Learnlift USA, 12 Greenway Plaza, Suite 1510, Houston, Texas 77046, support@memorylifter.com					*
 *																								*
 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License	*
 * as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.			*
 *																								*
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty	*
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.	*
 *																								*
 * You should have received a copy of the GNU Lesser General Public License along with this library; if not,					*
 * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA					*
 ***************************************************************************************************************************************/
// The following code was generated by Microsoft Visual Studio 2005.
// The test owner should check each test for validity.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using ICSharpCode.SharpZipLib.Zip;

using MLifter.BusinessLayer;
using MLifter.DAL;
using MLifter.DAL.Interfaces;
using MLifterTest;
using System.Reflection;
using MLifter.DAL.Tools;
using System.Globalization;
using System.Collections;

namespace MLifterTest.BusinessLayer
{
    /// <summary>
    ///This is a test class for MLifter.BusinessLayer.Dictionary and is intended
    ///to contain all MLifter.BusinessLayer.Dictionary Unit Tests
    ///</summary>
    [TestClass()]
    public class DictionaryTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }
        #region Additional test attributes - obsolete!
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            MyClassCleanup(); //in case the LM is still open from another test
            ExtractTestDictionary();
            InitializeDictionary();
            ExpandDictionary(target, 10);
        }
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //
        [ClassCleanup()]
        public static void MyClassCleanup()
        {
            if (target != null)
                target.Close();
            TestInfrastructure.MyClassCleanup();
        }
        //
        //Use TestInitialize to run code before running each test
        //
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //

        /// <summary>
        /// Extracts the test dictionary.
        /// </summary>
        /// <remarks>Documented by Dev02, 2008-05-16</remarks>
        public static void ExtractTestDictionary()
        {
            //extract test LM
            MemoryStream zipStream = new MemoryStream(Properties.Resources.StartupFolders);
            ZipInputStream zipFile = new ZipInputStream(zipStream);
            ZipEntry entry;

            while ((entry = zipFile.GetNextEntry()) != null)
            {
                string directoryName = Path.GetDirectoryName(entry.Name);
                string fileName = Path.GetFileName(entry.Name);

                if (directoryName.Length > 0)
                    Directory.CreateDirectory(directoryName);

                if (fileName.Length > 0)
                {
                    if (Path.GetExtension(fileName).ToLowerInvariant() == Helper.OdxExtension)
                        testDic = Path.Combine(directoryName, fileName);

                    FileStream stream = File.Open(Path.Combine(directoryName, fileName), FileMode.Create, FileAccess.Write, FileShare.None);
                    int bufferSize = 1024;
                    byte[] buffer = new byte[bufferSize];

                    while (bufferSize > 0)
                    {
                        bufferSize = zipFile.Read(buffer, 0, buffer.Length);
                        if (bufferSize > 0)
                            stream.Write(buffer, 0, bufferSize);
                    }

                    stream.Close();
                }
            }

            zipFile.Close();
        }

        public static string testDic = string.Empty;

        /// <summary>
        /// The testing target dictionary.
        /// </summary>
        public static Dictionary target = null;

        /// <summary>
        /// Initializes the dictionary.
        /// </summary>
        /// <returns></returns>
        /// <remarks>Documented by Dev02, 2008-05-16</remarks>
        public static void InitializeDictionary()
        {
            Assert.IsTrue(File.Exists(testDic), "Test Learning Module file cannot be found.");
            if (target != null)
                target.Close();
            IUser user = UserFactory.Create((GetLoginInformation)delegate(UserStruct u, ConnectionStringStruct c) { return u; },
                new ConnectionStringStruct(DatabaseType.Xml, DictionaryTest.testDic, false), (DataAccessErrorDelegate)delegate { return; }, testDic);
            target = new Dictionary(user.Open(), null);
        }

        #endregion

        #region Helper Methods

        /// <summary>
        /// Fills the boxes random.
        /// </summary>
        /// <remarks>Documented by Dev02, 2008-05-16</remarks>
        public static void FillBoxesRandom(Dictionary target)
        {
            Trace.WriteLine("Assigning card boxes randomly.");
            int boxcount = target.Boxes.Count;

            foreach (ICard card in target.Cards.Cards)
            {
                card.Box = random.Next(boxcount);
                if (card.Box == 6) //leave at least one box completely empty
                    card.Box = 0;
                card.Active = random.Next(3) > 0;
            }

            Trace.WriteLine("Assigning card boxes finished:");
            foreach (IBox box in target.Boxes)
                Trace.WriteLine(string.Format("Box {0}: {1} cards.", box.ToString(), box.CurrentSize));
            Trace.WriteLine(string.Format("Inactive: {0} of {1} cards.", target.Cards.Cards.Count - target.Cards.ActiveCardsCount, target.Cards.Cards.Count));
        }

        /// <summary>
        /// Fills the dictionary.
        /// </summary>
        /// <param name="target">The target.</param>
        /// <remarks>Documented by Dev02, 2008-09-10</remarks>
        public static void FillDictionary(Dictionary target)
        {
            int chapterId = target.Chapters.AddChapter("chapter", "");
            target.Cards.AddCard("Testcard", "Testcard", "", "", "stylesheet", "stylesheet", chapterId);
            ExpandDictionary(target, 10);
            FillBoxesRandom(target);
        }

        ///<summary>
        ///Expands the dictionary (Clones the cards).
        ///</summary>
        ///<param name="factor">The factor.</param>
        ///<remarks>Documented by Dev02, 2008-05-16</remarks>
        public static void ExpandDictionary(Dictionary target, int factor)
        {
            int count = factor * target.Cards.Cards.Count;
            Trace.WriteLine(string.Format("Expanding LM from {0} cards to {1} cards.", target.Cards.Cards.Count, count));
            for (int i = 0; i < count; i++)
            {
                ICard card = target.Cards.Cards[random.Next(target.Cards.Cards.Count)];

                ICard newcard = target.Cards.AddNew();

                foreach (IWord word in card.Answer.Words)
                    newcard.Answer.AddWord(newcard.Answer.CreateWord(word.Word + " " + i, word.Type, word.Default));
                foreach (IWord word in card.AnswerExample.Words)
                    newcard.AnswerExample.AddWord(newcard.AnswerExample.CreateWord(word.Word + " " + i, word.Type, word.Default));

                newcard.Chapter = card.Chapter;

                foreach (IWord word in card.Question.Words)
                    newcard.Question.AddWord(newcard.Question.CreateWord(word.Word + " " + i, word.Type, word.Default));
                foreach (IWord word in card.QuestionExample.Words)
                    newcard.QuestionExample.AddWord(newcard.QuestionExample.CreateWord(word.Word + " " + i, word.Type, word.Default));
            }
            Trace.WriteLine("Expanding finished.");
        }

        private static Random random = new Random((int)DateTime.Now.Ticks);

        /// <summary>
        /// Gets a random.
        /// </summary>
        /// <value>The random.</value>
        /// <remarks>Documented by Dev02, 2008-05-19</remarks>
        public static Random Random
        {
            get { return random; }
        }

        /// <summary>
        /// Gets a random bool value.
        /// </summary>
        /// <value><c>true</c> if [rand bool]; otherwise, <c>false</c>.</value>
        /// <remarks>Documented by Dev02, 2008-05-16</remarks>
        public static bool GetRandBool()
        {
            return (random.NextDouble() > 0.5);
        }

        /// <summary>
        /// Gets the target box.
        /// </summary>
        /// <param name="sourceBox">The source box.</param>
        /// <param name="promote">if set to <c>true</c> [promote].</param>
        /// <returns></returns>
        /// <remarks>Documented by Dev02, 2008-05-19</remarks>
        public static int GetTargetBox(int sourceBox, bool promote)
        {
            int targetbox;
            if (promote)
            {
                //promote card
                if (sourceBox == 0)
                    targetbox = 2;
                else if (sourceBox == -1)
                    targetbox = sourceBox;
                else
                    targetbox = Math.Min(target.Boxes.Count - 1, sourceBox + 1);
            }
            else
            {
                //demote card
                if (sourceBox == -1)
                    targetbox = sourceBox;
                else
                    targetbox = 1;
            }
            return targetbox;
        }
        #endregion

        /// <summary>
        /// A test for PromoteCard and DemoteCard (int)
        /// </summary>
        [TestMethod()]
        [TestProperty("BL", "DanAch"), DataSource("TestSources")]
        public void PromoteDemoteCardTest()
        {
            if (TestInfrastructure.IsActive(TestContext))
            {
                using (Dictionary target = TestInfrastructure.GetConnection(TestContext))
                {
                    FillDictionary(target);

                    int boxcount = target.Boxes.Count;

                    foreach (ICard card in target.Cards.Cards)
                    {
                        int prebox = card.Box;
                        bool cardactive = card.Active;
                        DateTime cardTimestamp = card.Timestamp;

                        bool promote = GetRandBool();
                        int targetbox = GetTargetBox(prebox, promote);

                        if (promote)
                            target.PromoteCard(card.Id);
                        else
                            target.DemoteCard(card.Id);

                        if (card.Active)
                            Assert.AreEqual(targetbox, card.Box, "Card did not go to the right box.");
                        Assert.AreEqual(card.Active, cardactive, "Card did not stay cardactive/not cardactive.");
                        if (card.Active)
                            Assert.AreNotEqual(Math.Abs(cardTimestamp.Ticks - card.Timestamp.Ticks) < 10, "Card timestamp was not actualized.");
                    }
                }
            }
        }

        /// <summary>
        ///A test for EnableCard (int, bool)
        ///</summary>
        [TestMethod()]
        [TestProperty("BL", "DanAch"), DataSource("TestSources")]
        public void EnableCardTest()
        {
            if (TestInfrastructure.IsActive(TestContext))
            {
                using (Dictionary target = TestInfrastructure.GetConnection(TestContext))
                {
                    FillDictionary(target);
                    foreach (ICard card in target.Cards.Cards)
                    {
                        if (!target.QueryChapters.Contains(card.Chapter))
                            target.QueryChapters.Add(card.Chapter);

                        Random random = new Random((int)DateTime.Now.Ticks);
                        int activeCardcount = target.Cards.ActiveCardsCount;
                        bool wasActive = card.Active;
                        int targetActiveCardCount = activeCardcount;

                        bool targetActive = (random.Next(2) > 0) ? true : false;
                        if (card.Active != targetActive)
                            targetActiveCardCount += (targetActive) ? 1 : -1;
                        card.Active = targetActive;

                        Assert.AreEqual(targetActive, card.Active, "Card was not enabled/disabled properly.");
                        Assert.IsTrue((targetActive && card.Box >= 0) || (!targetActive), "Cardbox was not set properly.");
                        Assert.AreEqual(targetActiveCardCount, target.Cards.ActiveCardsCount, "ActiveCardsCount does not correspond properly.");
                    }
                }
            }
        }

        /// <summary>
        ///A test for GetChoices (int)
        ///</summary>
        [TestMethod()]
        [TestProperty("BL", "DanAch"), DataSource("TestSources")]
        public void GetChoicesTest()
        {
            if (TestInfrastructure.IsActive(TestContext))
            {
                using (Dictionary target = TestInfrastructure.GetConnection(TestContext))
                {
                    FillDictionary(target);

                    //TODO allow multiple correct answers does not get tested yet

                    target.GetNextCard();
                    target.CurrentMultipleChoiceOptions.AllowMultipleCorrectAnswers = false;
                    Random random = new Random((int)DateTime.Now.Ticks);

                    foreach (ICard card in target.Cards.Cards)
                    {
                        target.CurrentMultipleChoiceOptions.AllowRandomDistractors = GetRandBool();

                        for (int numberOfChoices = 1; numberOfChoices < 100; numberOfChoices += 5) //100 is the maximum for the GetMultipleChoice Method
                        {
                            target.CurrentMultipleChoiceOptions.NumberOfChoices = numberOfChoices;
                            MultipleChoice actual = target.GetChoices(card);

                            //calculate number of choices that are available
                            int availableChoices;
                            if (target.CurrentMultipleChoiceOptions.AllowRandomDistractors.GetValueOrDefault())
                                availableChoices = target.Cards.Cards.Count;
                            else
                                availableChoices = 1 + ((target.CurrentQueryDirection == EQueryDirection.Question2Answer) ? card.AnswerDistractors.Words.Count : card.QuestionDistractors.Words.Count);

                            if (numberOfChoices <= availableChoices && (numberOfChoices > 1 || target.CurrentMultipleChoiceOptions.AllowRandomDistractors.GetValueOrDefault())) //GetChoices does not return anything for 1 choice when !AllowRandomDistractors
                            {
                                Assert.IsNotNull(actual, string.Format("GetChoices returned nothing, when it should have returned {0} choices out of {1} available.", numberOfChoices, availableChoices));
                                Assert.IsTrue(target.CurrentMultipleChoiceOptions.NumberOfChoices >= actual.Count);
                            }
                            else
                                Assert.IsTrue(actual.Count == 0, "GetChoices did not return null.");
                        }
                    }
                }
            }
        }

        /// <summary>
        ///A test for GetNextLearnMode ()
        ///</summary>
        [TestMethod()]
        [TestProperty("BL", "DanAch"), DataSource("TestSources")]
        public void GetNextLearnModeTest()
        {
            if (TestInfrastructure.IsActive(TestContext))
            {
                using (Dictionary target = TestInfrastructure.GetConnection(TestContext))
                {
                    FillDictionary(target);
                    for (int i = 0; i < 25; i++)
                    {
                        target.Settings.QueryTypes.Word = GetRandBool();
                        target.Settings.QueryTypes.Sentence = GetRandBool();
                        target.Settings.QueryTypes.MultipleChoice = GetRandBool();
                        target.Settings.QueryTypes.ListeningComprehension = GetRandBool();
                        target.Settings.QueryTypes.ImageRecognition = GetRandBool();

                        target.AllowedQueryTypes.Word = GetRandBool();
                        target.AllowedQueryTypes.Sentence = GetRandBool();
                        target.AllowedQueryTypes.MultipleChoice = GetRandBool();
                        target.AllowedQueryTypes.ListeningComprehension = GetRandBool();
                        target.AllowedQueryTypes.ImageRecognition = GetRandBool();

                        target.Settings.QueryDirections.Answer2Question = GetRandBool();
                        target.Settings.QueryDirections.Question2Answer = GetRandBool();
                        target.Settings.QueryDirections.Mixed = GetRandBool();

                        target.AllowedQueryDirections.Question2Answer = GetRandBool();
                        target.AllowedQueryDirections.Answer2Question = GetRandBool();
                        target.AllowedQueryDirections.Mixed = GetRandBool();

                        target.GetNextCard();
                        LearnModes actual = target.LearnMode;
                        EQueryDirection direction = target.CurrentQueryDirection;

                        Assert.IsTrue(actual != LearnModes.ImageRecognition || (target.Settings.QueryTypes.ImageRecognition.GetValueOrDefault() && target.AllowedQueryTypes.ImageRecognition.GetValueOrDefault()));
                        Assert.IsTrue(actual != LearnModes.ListeningComprehension || (target.Settings.QueryTypes.ListeningComprehension.GetValueOrDefault() && target.AllowedQueryTypes.ListeningComprehension.GetValueOrDefault()));
                        Assert.IsTrue(actual != LearnModes.MultipleChoice || (target.Settings.QueryTypes.MultipleChoice.GetValueOrDefault() && target.AllowedQueryTypes.MultipleChoice.GetValueOrDefault()));
                        Assert.IsTrue(actual != LearnModes.Sentence || (target.Settings.QueryTypes.Sentence.GetValueOrDefault() && target.AllowedQueryTypes.Sentence.GetValueOrDefault()));
                        //LearnModes.Word is the fallback and therefore cannot be tested

                        if (!target.AllowedQueryDirections.Mixed.GetValueOrDefault() && (target.AllowedQueryDirections.Question2Answer.GetValueOrDefault() || target.AllowedQueryDirections.Answer2Question.GetValueOrDefault()))
                        {
                            Assert.IsTrue(direction != EQueryDirection.Question2Answer || target.AllowedQueryDirections.Question2Answer.GetValueOrDefault(), "QueryDirection Question2Answer is not allowed, but active.");
                            Assert.IsTrue(direction != EQueryDirection.Answer2Question || target.AllowedQueryDirections.Answer2Question.GetValueOrDefault(), "QueryDirection Answer2Question is not allowed, but active.");
                        }

                        Assert.IsTrue(direction != EQueryDirection.Mixed, "QueryDirection.Mixed is not allowed as current QueryDirection.");
                    }
                }
            }
        }


        /// <summary>
        /// A test for GetNextCard ()
        /// </summary>
        [TestMethod()]
        [TestProperty("BL", "DanAch"), DataSource("TestSources")]
        public void GetNextCardTest()
        {
            if (TestInfrastructure.IsActive(TestContext))
            {
                using (Dictionary target = TestInfrastructure.GetConnection(TestContext))
                {
                    FillDictionary(target);
                    for (int currentBox = 0; currentBox < target.Boxes.Count; currentBox++)
                    {
                        target.LearningBox = currentBox;
                        int cardsinbox;

                        for (int i = 0; i < 10; i++)
                        {
                            if (currentBox == 0)
                                cardsinbox = target.Cards.ActiveCardsCount;
                            else
                                cardsinbox = target.Boxes[currentBox].CurrentSize;

                            int cardid = -1;

                            cardid = target.GetNextCard().Id;
                            if (cardid >= 0)
                                if (GetRandBool())
                                    target.PromoteCard(cardid);
                                else
                                    target.DemoteCard(cardid);

                            Assert.IsTrue(cardid >= 0 || cardsinbox == 0, string.Format("Did not get a valid card ID, although there should be {0} cards in box no {1}.", cardsinbox, currentBox));
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Test the Box propertie of a card.
        /// </summary>
        /// <remarks>Documented by Dev05, 2008-09-05</remarks>
        [TestMethod]
        [TestProperty("BL", "ChrFin"), DataSource("TestSources")]
        public void CardBoxTest()
        {
            if (TestInfrastructure.IsActive(TestContext))
            {
                using (Dictionary dictionary = TestInfrastructure.GetConnection(TestContext))
                {
                    dictionary.DictionaryDAL.Cards.ClearAllBoxes();

                    IChapter chapter = dictionary.DictionaryDAL.Chapters.AddNew();

                    ICard newCard = dictionary.Cards.AddNew();
                    newCard.Chapter = chapter.Id;
                    newCard.Box = 0;

                    Card card = dictionary.Cards.GetCardByID(newCard.Id);
                    Assert.AreEqual<int>(0, card.BaseCard.Box, "Box not set to Pool");
                    card.BaseCard.Box = 5;
                    Assert.AreEqual<int>(5, newCard.Box, "Box not set to Box 5");
                }
            }
        }

        [TestMethod]
        [TestProperty("BL", "DanAch"), DataSource("TestSources")]
        public void ResetLearningProgressTest()
        {
            if (TestInfrastructure.IsActive(TestContext))
            {
                using (Dictionary dictionary = TestInfrastructure.GetConnection(TestContext))
                {
                    FillDictionary(dictionary);

                    dictionary.Highscore = 50;

                    dictionary.ResetLearningProgress();

                    //QC are not any more resetted!!!
                    //Assert.AreEqual(0, dictionary.QueryChapters.Count, "QueryChapters were not resetted.");

                    foreach (ICard card in dictionary.Cards.Cards)
                        Assert.IsTrue(card.Box < 1, "Card box not resetted.");

                    int cardCount = dictionary.Cards.Cards.Count;
                    foreach (IBox box in dictionary.Boxes)
                    {
                        int boxCurrentSize = box.CurrentSize;
                        if (box.Id == 0)
                            Assert.AreEqual(cardCount, boxCurrentSize, "Not all cards went to the Pool.");
                        else
                            Assert.AreEqual(0, boxCurrentSize, "Box is not empty.");
                    }

                    Assert.AreEqual(0, dictionary.Score, "Score was not resetted.");
                    Assert.AreEqual(0, dictionary.Highscore, "Highscore was not resetted.");
                }
            }
        }

        /// <summary>
        /// Tests the user settings.
        /// </summary>
        /// <remarks>Documented by Dev05, 2008-10-02</remarks>
        [TestMethod]
        [TestProperty("BL", "ChrFin"), DataSource("TestSources")]
        public void TestUserSettings()
        {
            if (TestInfrastructure.IsActive(TestContext))
            {
                using (Dictionary dictionary = TestInfrastructure.GetConnection(TestContext))
                {
                    if (!dictionary.IsDB)
                        return;

                    bool tstBool = true;
                    bool tstUsrBool = false;

                    int tstInt = 1;
                    int tstUsrInt = 3;

                    string tstStr = "mlifter";
                    string tstUsrStr = tstStr + "_user";

                    CultureInfo tstClt = new CultureInfo("de-AT");
                    CultureInfo tstUsrClt = new CultureInfo("en-US");

                    ISettings defaultSettings = dictionary.DictionaryDAL.DefaultSettings;
                    ISettings userSettings = dictionary.DictionaryDAL.UserSettings;
                    ISettings settings = dictionary.Settings;

                    # region testing AnswerCaption

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.AnswerCaption = tstStr;
                    Assert.AreEqual<string>(tstStr, settings.AnswerCaption, "Property not read correctly!");
                    Assert.AreEqual(string.Empty, userSettings.AnswerCaption, "Usersetting is not untouched!");
                    userSettings.AnswerCaption = tstUsrStr;
                    Assert.AreEqual<string>(tstUsrStr, settings.AnswerCaption, "Property not read correctly!");
                    Assert.AreNotEqual<string>(defaultSettings.AnswerCaption, userSettings.AnswerCaption, "Usersettings saved to default settings!");

                    #endregion
                    # region testing AnswerCulture

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.AnswerCulture = tstClt;
                    Assert.AreEqual<CultureInfo>(tstClt, settings.AnswerCulture, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.AnswerCulture, "Usersetting is not untouched!");
                    userSettings.AnswerCulture = tstUsrClt;
                    Assert.AreEqual<CultureInfo>(tstUsrClt, settings.AnswerCulture, "Property not read correctly!");
                    Assert.AreNotEqual<CultureInfo>(defaultSettings.AnswerCulture, userSettings.AnswerCulture, "Usersettings saved to default settings!");

                    #endregion
                    # region testing AutoBoxSize

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.AutoBoxSize = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.AutoBoxSize, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.AutoBoxSize, "Usersetting is not untouched!");
                    userSettings.AutoBoxSize = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.AutoBoxSize, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.AutoBoxSize, userSettings.AutoBoxSize, "Usersettings saved to default settings!");

                    #endregion
                    # region testing AutoplayAudio

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.AutoplayAudio = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.AutoplayAudio, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.AutoplayAudio, "Usersetting is not untouched!");
                    userSettings.AutoplayAudio = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.AutoplayAudio, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.AutoplayAudio, userSettings.AutoplayAudio, "Usersettings saved to default settings!");

                    #endregion
                    # region testing CaseSensitive

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.CaseSensitive = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.CaseSensitive, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.CaseSensitive, "Usersetting is not untouched!");
                    userSettings.CaseSensitive = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.CaseSensitive, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.CaseSensitive, userSettings.CaseSensitive, "Usersettings saved to default settings!");

                    #endregion
                    # region testing ConfirmDemote

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.ConfirmDemote = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.ConfirmDemote, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.ConfirmDemote, "Usersetting is not untouched!");
                    userSettings.ConfirmDemote = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.ConfirmDemote, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.ConfirmDemote, userSettings.ConfirmDemote, "Usersettings saved to default settings!");

                    #endregion
                    # region testing CorrectOnTheFly

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.CorrectOnTheFly = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.CorrectOnTheFly, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.CorrectOnTheFly, "Usersetting is not untouched!");
                    userSettings.CorrectOnTheFly = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.CorrectOnTheFly, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.CorrectOnTheFly, userSettings.CorrectOnTheFly, "Usersettings saved to default settings!");

                    #endregion
                    # region testing EnableCommentary

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.EnableCommentary = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.EnableCommentary, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.EnableCommentary, "Usersetting is not untouched!");
                    userSettings.EnableCommentary = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.EnableCommentary, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.EnableCommentary, userSettings.EnableCommentary, "Usersettings saved to default settings!");

                    #endregion
                    # region testing EnableTimer

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.EnableTimer = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.EnableTimer, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.EnableTimer, "Usersetting is not untouched!");
                    userSettings.EnableTimer = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.EnableTimer, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.EnableTimer, userSettings.EnableTimer, "Usersettings saved to default settings!");

                    #endregion

                    # region testing GradeSynonyms.AllKnown

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.GradeSynonyms.AllKnown = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.GradeSynonyms.AllKnown, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.GradeSynonyms.AllKnown, "Usersetting is not untouched!");
                    userSettings.GradeSynonyms.AllKnown = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.GradeSynonyms.AllKnown, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.GradeSynonyms.AllKnown, userSettings.GradeSynonyms.AllKnown, "Usersettings saved to default settings!");

                    #endregion
                    # region testing GradeSynonyms.FirstKnown

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.GradeSynonyms.FirstKnown = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.GradeSynonyms.FirstKnown, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.GradeSynonyms.FirstKnown, "Usersetting is not untouched!");
                    userSettings.GradeSynonyms.FirstKnown = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.GradeSynonyms.FirstKnown, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.GradeSynonyms.FirstKnown, userSettings.GradeSynonyms.FirstKnown, "Usersettings saved to default settings!");

                    #endregion
                    # region testing GradeSynonyms.HalfKnown

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.GradeSynonyms.HalfKnown = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.GradeSynonyms.HalfKnown, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.GradeSynonyms.HalfKnown, "Usersetting is not untouched!");
                    userSettings.GradeSynonyms.HalfKnown = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.GradeSynonyms.HalfKnown, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.GradeSynonyms.HalfKnown, userSettings.GradeSynonyms.HalfKnown, "Usersettings saved to default settings!");

                    #endregion
                    # region testing GradeSynonyms.OneKnown

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.GradeSynonyms.OneKnown = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.GradeSynonyms.OneKnown, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.GradeSynonyms.OneKnown, "Usersetting is not untouched!");
                    userSettings.GradeSynonyms.OneKnown = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.GradeSynonyms.OneKnown, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.GradeSynonyms.OneKnown, userSettings.GradeSynonyms.OneKnown, "Usersettings saved to default settings!");

                    #endregion
                    # region testing GradeSynonyms.Prompt

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.GradeSynonyms.Prompt = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.GradeSynonyms.Prompt, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.GradeSynonyms.Prompt, "Usersetting is not untouched!");
                    userSettings.GradeSynonyms.Prompt = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.GradeSynonyms.Prompt, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.GradeSynonyms.Prompt, userSettings.GradeSynonyms.Prompt, "Usersettings saved to default settings!");

                    #endregion

                    # region testing GradeTyping.AllCorrect

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.GradeTyping.AllCorrect = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.GradeTyping.AllCorrect, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.GradeTyping.AllCorrect, "Usersetting is not untouched!");
                    userSettings.GradeTyping.AllCorrect = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.GradeTyping.AllCorrect, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.GradeTyping.AllCorrect, userSettings.GradeTyping.AllCorrect, "Usersettings saved to default settings!");

                    #endregion
                    # region testing GradeTyping.HalfCorrect

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.GradeTyping.HalfCorrect = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.GradeTyping.HalfCorrect, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.GradeTyping.HalfCorrect, "Usersetting is not untouched!");
                    userSettings.GradeTyping.HalfCorrect = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.GradeTyping.HalfCorrect, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.GradeTyping.HalfCorrect, userSettings.GradeTyping.HalfCorrect, "Usersettings saved to default settings!");

                    #endregion
                    # region testing GradeTyping.NoneCorrect

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.GradeTyping.NoneCorrect = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.GradeTyping.NoneCorrect, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.GradeTyping.NoneCorrect, "Usersetting is not untouched!");
                    userSettings.GradeTyping.NoneCorrect = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.GradeTyping.NoneCorrect, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.GradeTyping.NoneCorrect, userSettings.GradeTyping.NoneCorrect, "Usersettings saved to default settings!");

                    #endregion
                    # region testing GradeTyping.Prompt

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.GradeTyping.Prompt = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.GradeTyping.Prompt, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.GradeTyping.Prompt, "Usersetting is not untouched!");
                    userSettings.GradeTyping.Prompt = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.GradeTyping.Prompt, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.GradeTyping.Prompt, userSettings.GradeTyping.Prompt, "Usersettings saved to default settings!");

                    #endregion

                    # region testing MultipleChoiceOptions.AllowMultipleCorrectAnswers

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.MultipleChoiceOptions.AllowMultipleCorrectAnswers = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.MultipleChoiceOptions.AllowMultipleCorrectAnswers, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.MultipleChoiceOptions.AllowMultipleCorrectAnswers, "Usersetting is not untouched!");
                    userSettings.MultipleChoiceOptions.AllowMultipleCorrectAnswers = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.MultipleChoiceOptions.AllowMultipleCorrectAnswers, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.MultipleChoiceOptions.AllowMultipleCorrectAnswers, userSettings.MultipleChoiceOptions.AllowMultipleCorrectAnswers, "Usersettings saved to default settings!");

                    #endregion
                    # region testing MultipleChoiceOptions.AllowRandomDistractors

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.MultipleChoiceOptions.AllowRandomDistractors = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.MultipleChoiceOptions.AllowRandomDistractors, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.MultipleChoiceOptions.AllowRandomDistractors, "Usersetting is not untouched!");
                    userSettings.MultipleChoiceOptions.AllowRandomDistractors = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.MultipleChoiceOptions.AllowRandomDistractors, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.MultipleChoiceOptions.AllowRandomDistractors, userSettings.MultipleChoiceOptions.AllowRandomDistractors, "Usersettings saved to default settings!");

                    #endregion
                    # region testing MultipleChoiceOptions.MaxNumberOfCorrectAnswers

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.MultipleChoiceOptions.MaxNumberOfCorrectAnswers = tstInt;
                    Assert.AreEqual<int?>(tstInt, settings.MultipleChoiceOptions.MaxNumberOfCorrectAnswers, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.MultipleChoiceOptions.MaxNumberOfCorrectAnswers, "Usersetting is not untouched!");
                    userSettings.MultipleChoiceOptions.MaxNumberOfCorrectAnswers = tstUsrInt;
                    Assert.AreEqual<int?>(tstUsrInt, settings.MultipleChoiceOptions.MaxNumberOfCorrectAnswers, "Property not read correctly!");
                    Assert.AreNotEqual<int?>(defaultSettings.MultipleChoiceOptions.MaxNumberOfCorrectAnswers, userSettings.MultipleChoiceOptions.MaxNumberOfCorrectAnswers, "Usersettings saved to default settings!");

                    #endregion
                    # region testing MultipleChoiceOptions.NumberOfChoices

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.MultipleChoiceOptions.NumberOfChoices = tstInt;
                    Assert.AreEqual<int?>(tstInt, settings.MultipleChoiceOptions.NumberOfChoices, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.MultipleChoiceOptions.NumberOfChoices, "Usersetting is not untouched!");
                    userSettings.MultipleChoiceOptions.NumberOfChoices = tstUsrInt;
                    Assert.AreEqual<int?>(tstUsrInt, settings.MultipleChoiceOptions.NumberOfChoices, "Property not read correctly!");
                    Assert.AreNotEqual<int?>(defaultSettings.MultipleChoiceOptions.NumberOfChoices, userSettings.MultipleChoiceOptions.NumberOfChoices, "Usersettings saved to default settings!");

                    #endregion

                    # region testing PoolEmptyMessageShown

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.PoolEmptyMessageShown = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.PoolEmptyMessageShown, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.PoolEmptyMessageShown, "Usersetting is not untouched!");
                    userSettings.PoolEmptyMessageShown = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.PoolEmptyMessageShown, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.PoolEmptyMessageShown, userSettings.PoolEmptyMessageShown, "Usersettings saved to default settings!");

                    #endregion

                    # region testing QueryDirections.Answer2Question

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.QueryDirections.Answer2Question = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.QueryDirections.Answer2Question, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.QueryDirections.Answer2Question, "Usersetting is not untouched!");
                    userSettings.QueryDirections.Answer2Question = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.QueryDirections.Answer2Question, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.QueryDirections.Answer2Question, userSettings.QueryDirections.Answer2Question, "Usersettings saved to default settings!");

                    #endregion
                    # region testing QueryDirections.Mixed

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.QueryDirections.Mixed = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.QueryDirections.Mixed, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.QueryDirections.Mixed, "Usersetting is not untouched!");
                    userSettings.QueryDirections.Mixed = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.QueryDirections.Mixed, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.QueryDirections.Mixed, userSettings.QueryDirections.Mixed, "Usersettings saved to default settings!");

                    #endregion
                    # region testing QueryDirections.Question2Answer

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.QueryDirections.Question2Answer = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.QueryDirections.Question2Answer, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.QueryDirections.Question2Answer, "Usersetting is not untouched!");
                    userSettings.QueryDirections.Question2Answer = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.QueryDirections.Question2Answer, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.QueryDirections.Question2Answer, userSettings.QueryDirections.Question2Answer, "Usersettings saved to default settings!");

                    #endregion

                    # region testing QueryTypes.ImageRecognition

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.QueryTypes.ImageRecognition = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.QueryTypes.ImageRecognition, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.QueryTypes.ImageRecognition, "Usersetting is not untouched!");
                    userSettings.QueryTypes.ImageRecognition = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.QueryTypes.ImageRecognition, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.QueryTypes.ImageRecognition, userSettings.QueryTypes.ImageRecognition, "Usersettings saved to default settings!");

                    #endregion
                    # region testing QueryTypes.ListeningComprehension

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.QueryTypes.ListeningComprehension = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.QueryTypes.ListeningComprehension, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.QueryTypes.ListeningComprehension, "Usersetting is not untouched!");
                    userSettings.QueryTypes.ListeningComprehension = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.QueryTypes.ListeningComprehension, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.QueryTypes.ListeningComprehension, userSettings.QueryTypes.ListeningComprehension, "Usersettings saved to default settings!");

                    #endregion
                    # region testing QueryTypes.MultipleChoice

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.QueryTypes.MultipleChoice = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.QueryTypes.MultipleChoice, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.QueryTypes.MultipleChoice, "Usersetting is not untouched!");
                    userSettings.QueryTypes.MultipleChoice = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.QueryTypes.MultipleChoice, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.QueryTypes.MultipleChoice, userSettings.QueryTypes.MultipleChoice, "Usersettings saved to default settings!");

                    #endregion
                    # region testing QueryTypes.Sentence

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.QueryTypes.Sentence = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.QueryTypes.Sentence, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.QueryTypes.Sentence, "Usersetting is not untouched!");
                    userSettings.QueryTypes.Sentence = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.QueryTypes.Sentence, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.QueryTypes.Sentence, userSettings.QueryTypes.Sentence, "Usersettings saved to default settings!");

                    #endregion
                    # region testing QueryTypes.Word

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.QueryTypes.Word = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.QueryTypes.Word, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.QueryTypes.Word, "Usersetting is not untouched!");
                    userSettings.QueryTypes.Word = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.QueryTypes.Word, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.QueryTypes.Word, userSettings.QueryTypes.Word, "Usersettings saved to default settings!");

                    #endregion

                    # region testing QuestionCaption

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.QuestionCaption = tstStr;
                    Assert.AreEqual<string>(tstStr, settings.QuestionCaption, "Property not read correctly!");
                    Assert.AreEqual(string.Empty, userSettings.QuestionCaption, "Usersetting is not untouched!");
                    userSettings.QuestionCaption = tstUsrStr;
                    Assert.AreEqual<string>(tstUsrStr, settings.QuestionCaption, "Property not read correctly!");
                    Assert.AreNotEqual<string>(defaultSettings.QuestionCaption, userSettings.QuestionCaption, "Usersettings saved to default settings!");

                    #endregion
                    # region testing QuestionCulture

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.QuestionCulture = tstClt;
                    Assert.AreEqual<CultureInfo>(tstClt, settings.QuestionCulture, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.QuestionCulture, "Usersetting is not untouched!");
                    userSettings.QuestionCulture = tstUsrClt;
                    Assert.AreEqual<CultureInfo>(tstUsrClt, settings.QuestionCulture, "Property not read correctly!");
                    Assert.AreNotEqual<CultureInfo>(defaultSettings.QuestionCulture, userSettings.QuestionCulture, "Usersettings saved to default settings!");

                    #endregion
                    # region testing RandomPool

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.RandomPool = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.RandomPool, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.RandomPool, "Usersetting is not untouched!");
                    userSettings.RandomPool = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.RandomPool, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.RandomPool, userSettings.RandomPool, "Usersettings saved to default settings!");

                    #endregion
                    # region testing SelfAssessment

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.SelfAssessment = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.SelfAssessment, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.SelfAssessment, "Usersetting is not untouched!");
                    userSettings.SelfAssessment = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.SelfAssessment, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.SelfAssessment, userSettings.SelfAssessment, "Usersettings saved to default settings!");

                    #endregion
                    # region testing ShowImages

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.ShowImages = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.ShowImages, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.ShowImages, "Usersetting is not untouched!");
                    userSettings.ShowImages = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.ShowImages, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.ShowImages, userSettings.ShowImages, "Usersettings saved to default settings!");

                    #endregion
                    # region testing ShowStatistics

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.ShowStatistics = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.ShowStatistics, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.ShowStatistics, "Usersetting is not untouched!");
                    userSettings.ShowStatistics = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.ShowStatistics, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.ShowStatistics, userSettings.ShowStatistics, "Usersettings saved to default settings!");

                    #endregion
                    # region testing SkipCorrectAnswers

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.SkipCorrectAnswers = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.SkipCorrectAnswers, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.SkipCorrectAnswers, "Usersetting is not untouched!");
                    userSettings.SkipCorrectAnswers = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.SkipCorrectAnswers, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.SkipCorrectAnswers, userSettings.SkipCorrectAnswers, "Usersettings saved to default settings!");

                    #endregion

                    # region testing SnoozeOptions.IsCardsEnabled

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.SnoozeOptions.IsCardsEnabled = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.SnoozeOptions.IsCardsEnabled, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.SnoozeOptions.IsCardsEnabled, "Usersetting is not untouched!");
                    userSettings.SnoozeOptions.IsCardsEnabled = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.SnoozeOptions.IsCardsEnabled, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.SnoozeOptions.IsCardsEnabled, userSettings.SnoozeOptions.IsCardsEnabled, "Usersettings saved to default settings!");

                    #endregion
                    # region testing SnoozeOptions.IsRightsEnabled

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.SnoozeOptions.IsRightsEnabled = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.SnoozeOptions.IsRightsEnabled, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.SnoozeOptions.IsRightsEnabled, "Usersetting is not untouched!");
                    userSettings.SnoozeOptions.IsRightsEnabled = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.SnoozeOptions.IsRightsEnabled, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.SnoozeOptions.IsRightsEnabled, userSettings.SnoozeOptions.IsRightsEnabled, "Usersettings saved to default settings!");

                    #endregion
                    # region testing SnoozeOptions.IsTimeEnabled

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.SnoozeOptions.IsTimeEnabled = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.SnoozeOptions.IsTimeEnabled, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.SnoozeOptions.IsTimeEnabled, "Usersetting is not untouched!");
                    userSettings.SnoozeOptions.IsTimeEnabled = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.SnoozeOptions.IsTimeEnabled, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.SnoozeOptions.IsTimeEnabled, userSettings.SnoozeOptions.IsTimeEnabled, "Usersettings saved to default settings!");

                    #endregion
                    # region testing SnoozeOptions.SnoozeCards

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.SnoozeOptions.SnoozeCards = tstInt;
                    Assert.AreEqual<int?>(tstInt, settings.SnoozeOptions.SnoozeCards, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.SnoozeOptions.SnoozeCards, "Usersetting is not untouched!");
                    userSettings.SnoozeOptions.SnoozeCards = tstUsrInt;
                    Assert.AreEqual<int?>(tstUsrInt, settings.SnoozeOptions.SnoozeCards, "Property not read correctly!");
                    Assert.AreNotEqual<int?>(defaultSettings.SnoozeOptions.SnoozeCards, userSettings.SnoozeOptions.SnoozeCards, "Usersettings saved to default settings!");

                    #endregion
                    # region testing SnoozeOptions.SnoozeHigh

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.SnoozeOptions.SnoozeHigh = tstInt;
                    Assert.AreEqual<int?>(tstInt, settings.SnoozeOptions.SnoozeHigh, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.SnoozeOptions.SnoozeHigh, "Usersetting is not untouched!");
                    userSettings.SnoozeOptions.SnoozeHigh = tstUsrInt;
                    Assert.AreEqual<int?>(tstUsrInt, settings.SnoozeOptions.SnoozeHigh, "Property not read correctly!");
                    Assert.AreNotEqual<int?>(defaultSettings.SnoozeOptions.SnoozeHigh, userSettings.SnoozeOptions.SnoozeHigh, "Usersettings saved to default settings!");

                    #endregion
                    # region testing SnoozeOptions.SnoozeLow

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.SnoozeOptions.SnoozeLow = tstInt;
                    Assert.AreEqual<int?>(tstInt, settings.SnoozeOptions.SnoozeLow, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.SnoozeOptions.SnoozeLow, "Usersetting is not untouched!");
                    userSettings.SnoozeOptions.SnoozeLow = tstUsrInt;
                    Assert.AreEqual<int?>(tstUsrInt, settings.SnoozeOptions.SnoozeLow, "Property not read correctly!");
                    Assert.AreNotEqual<int?>(defaultSettings.SnoozeOptions.SnoozeLow, userSettings.SnoozeOptions.SnoozeLow, "Usersettings saved to default settings!");

                    #endregion
                    # region testing SnoozeOptions.SnoozeRights

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.SnoozeOptions.SnoozeRights = tstInt;
                    Assert.AreEqual<int?>(tstInt, settings.SnoozeOptions.SnoozeRights, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.SnoozeOptions.SnoozeRights, "Usersetting is not untouched!");
                    userSettings.SnoozeOptions.SnoozeRights = tstUsrInt;
                    Assert.AreEqual<int?>(tstUsrInt, settings.SnoozeOptions.SnoozeRights, "Property not read correctly!");
                    Assert.AreNotEqual<int?>(defaultSettings.SnoozeOptions.SnoozeRights, userSettings.SnoozeOptions.SnoozeRights, "Usersettings saved to default settings!");

                    #endregion
                    # region testing SnoozeOptions.SnoozeTime

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.SnoozeOptions.SnoozeTime = tstInt;
                    Assert.AreEqual<int?>(tstInt, settings.SnoozeOptions.SnoozeTime, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.SnoozeOptions.SnoozeTime, "Usersetting is not untouched!");
                    userSettings.SnoozeOptions.SnoozeTime = tstUsrInt;
                    Assert.AreEqual<int?>(tstUsrInt, settings.SnoozeOptions.SnoozeTime, "Property not read correctly!");
                    Assert.AreNotEqual<int?>(defaultSettings.SnoozeOptions.SnoozeTime, userSettings.SnoozeOptions.SnoozeTime, "Usersettings saved to default settings!");

                    #endregion

                    # region testing StripChars

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.StripChars = tstStr;
                    Assert.AreEqual<string>(tstStr, settings.StripChars, "Property not read correctly!");
                    Assert.AreEqual(string.Empty, userSettings.StripChars, "Usersetting is not untouched!");
                    userSettings.StripChars = tstUsrStr;
                    Assert.AreEqual<string>(tstUsrStr, settings.StripChars, "Property not read correctly!");
                    Assert.AreNotEqual<string>(defaultSettings.StripChars, userSettings.StripChars, "Usersettings saved to default settings!");

                    #endregion
                    # region testing UseLMStylesheets

                    CleanProperties(defaultSettings);
                    CleanProperties(userSettings);

                    defaultSettings.UseLMStylesheets = tstBool;
                    Assert.AreEqual<bool?>(tstBool, settings.UseLMStylesheets, "Property not read correctly!");
                    Assert.AreEqual(null, userSettings.UseLMStylesheets, "Usersetting is not untouched!");
                    userSettings.UseLMStylesheets = tstUsrBool;
                    Assert.AreEqual<bool?>(tstUsrBool, settings.UseLMStylesheets, "Property not read correctly!");
                    Assert.AreNotEqual<bool?>(defaultSettings.UseLMStylesheets, userSettings.UseLMStylesheets, "Usersettings saved to default settings!");

                    #endregion
                }
            }
        }

        /// <summary>
        /// Cleans the properties of the given object.
        /// </summary>
        /// <param name="objectToClean">The object to clean.</param>
        /// <remarks>Documented by Dev05, 2008-10-02</remarks>
        private void CleanProperties(object objectToClean)
        {
            if (objectToClean == null)
                return;

            foreach (PropertyInfo info in objectToClean.GetType().GetProperties())
            {
                try
                {
                    if (typeof(ICopy).IsAssignableFrom(info.PropertyType))
                        CleanProperties(info.GetValue(objectToClean, null));
                    else if (typeof(ICollection).IsAssignableFrom(info.PropertyType) && info.PropertyType.GetMethod("Clear") != null)
                        info.PropertyType.GetMethod("Clear").Invoke(info.GetValue(objectToClean, null), null);
                    else if (info.CanWrite)
                        info.SetValue(objectToClean, null, null);
                }
                catch (Exception ex) { Debug.WriteLine(ex.ToString()); }
            }
        }
    }
}
